"""
元数据管理模块 - 阶段2：元数据获取和解析
"""
import json
from typing import Dict, Any, List, Optional
import requests
import urllib3
from jsonschema import validate, ValidationError
from config.config import settings
from utils.logger import app_logger
from models.field_schema import FieldSchema
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from src.auth.auth_manager import auth_manager

# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class MetadataManager:
    """元数据管理器"""
    
    def __init__(self):
        self.session = requests.Session()
        self.session.timeout = settings.REQUEST_TIMEOUT
        
        # 禁用SSL证书验证以解决证书验证失败问题
        self.session.verify = False
        
        # 定义支持的13个字段类型（根据自动测试用例生成格式规范）
        self.supported_field_types = {
            "formula",      # _name - 公式型，返回多语言类型
            "text",         # text_7ea7d6a3339 - 文本
            "bigint",       # bigint_7d6a33398bf - 整数
            "number",       # number_a33398bfae5 - 浮点数
            "date",         # date_398bfae52d8 - 日期
            "datetime",     # datetime_bfae52d8694 - 日期时间
            "option",       # option_e52d86948bb - 选项
            "boolean",      # boolean_e206a267520 - 布尔
            "richText",     # richText_76d22d35024 - 富文本
            "multilingual", # multilingual_24673c280f2 - 多语文本
            "mobileNumber", # phone_73c280f2783 - 手机号码
            "email",        # email_f2783b49d9a - 邮箱
            "decimal"       # decimal_a446e77c109 - 定点数
        }
        
    def get_object_metadata(self, object_name: str) -> Optional[Dict[str, Any]]:
        """
        获取对象元数据
        
        Args:
            object_name: 对象名称（如：object_cbb246f2bd1）
            
        Returns:
            对象元数据或None
        """
        try:
            app_logger.info(f"开始获取对象元数据：{object_name}")
            
            # 获取认证头
            auth_headers = auth_manager.get_auth_headers()
            if not auth_headers:
                app_logger.error("无法获取认证头，请先初始化认证")
                return None
            
            # 构建请求URL - 使用NAMESPACE动态构建
            base_url = "https://ae-openapi.feishu.cn/api/data/v1"
            namespace = settings.NAMESPACE
            url = f"{base_url}/namespaces/{namespace}/meta/objects/{object_name}"
            app_logger.info(f"请求URL: {url}")
            
            # 发送请求
            response = self.session.get(url, headers=auth_headers)
            
            if response.status_code == 200:
                response_data = response.json()
                app_logger.info(f"API响应: {response_data.get('code', 'unknown')}")
                
                # 解析飞书API响应格式
                if response_data.get("code") == "0":
                    metadata = response_data.get("data", {})
                    app_logger.info(f"成功获取对象元数据：{object_name}，包含{len(metadata.get('fields', []))}个字段")
                    return metadata
                else:
                    app_logger.error(f"API返回错误: {response_data.get('msg', '未知错误')}")
                    return None
            else:
                app_logger.error(f"获取元数据失败，状态码：{response.status_code}，响应：{response.text}")
                return None
                
        except Exception as e:
            app_logger.error(f"获取对象元数据异常：{str(e)}")
            return None
    
    def parse_fields(self, metadata: Dict[str, Any]) -> List[Dict[str, Any]]:
        """
        解析飞书API返回的字段信息 - 存储所有字段类型
        
        Args:
            metadata: 飞书API返回的对象元数据
            
        Returns:
            解析后的字段信息列表
        """
        try:
            app_logger.info("开始解析飞书API字段信息")
            
            fields = []
            fields_data = metadata.get("fields", [])
            total_fields = len(fields_data)
            
            for field_info in fields_data:
                field_type = field_info.get("type", {}).get("name", "text")
                
                # 存储所有字段类型，不再过滤
                field_data = {
                    "field_api_name": field_info.get("apiName", ""),
                    "field_label_zh": field_info.get("label", {}).get("zh_CN", ""),
                    "field_label_en": field_info.get("label", {}).get("en_US", ""),
                    "field_type": self._get_field_type_from_feishu(field_info.get("type", {})),
                    "is_required": self._is_field_required(field_info.get("type", {})),
                    "is_unique": self._is_field_unique(field_info.get("type", {})),
                    "is_multiple": self._is_field_multiple(field_info.get("type", {})),
                    "generation_rules": self._extract_generation_rules(field_info.get("type", {}))
                }
                fields.append(field_data)
                
            app_logger.info(f"成功解析字段信息，共{len(fields)}个字段（总计{total_fields}个字段）")
            return fields
            
        except Exception as e:
            app_logger.error(f"解析字段信息异常：{str(e)}")
            return []
    
    def _get_field_type_from_feishu(self, type_info: Dict[str, Any]) -> str:
        """
        获取飞书API字段类型 - 支持所有字段类型
        
        Args:
            type_info: 字段类型信息
            
        Returns:
            字段类型
        """
        field_type = type_info.get("name", "text")
        
        # 飞书字段类型映射 - 支持所有字段类型
        type_mapping = {
            "text": "text",                    # 文本
            "bigint": "bigint",                # 整数
            "number": "number",                # 浮点数
            "decimal": "decimal",              # 定点数
            "boolean": "boolean",              # 布尔
            "date": "date",                    # 日期
            "datetime": "datetime",            # 日期时间
            "option": "option",                # 选项
            "richText": "richText",            # 富文本
            "multilingual": "multilingual",    # 多语文本
            "mobileNumber": "mobileNumber",    # 手机号码
            "email": "email",                  # 邮箱
            "formula": "formula",              # 公式型（多语言）
            "lookup": "lookup",                # 关联字段
            "file": "file",                    # 文件
            "autoId": "auto_id",               # 自动编号
            "rollup": "rollup",                # 汇总字段
            "referenceField": "reference_field", # 引用字段
            "region": "region",                # 地区
            "avatarOrLogo": "avatar_or_logo",  # 头像或Logo
            "auto_id": "auto_id",              # 自动编号（别名）
            "reference_field": "reference_field", # 引用字段（别名）
            "avatar_or_logo": "avatar_or_logo"  # 头像或Logo（别名）
        }
        
        return type_mapping.get(field_type, field_type)
    
    def _is_field_required(self, type_info: Dict[str, Any]) -> bool:
        """
        判断字段是否必填
        
        Args:
            type_info: 字段类型信息
            
        Returns:
            是否必填
        """
        settings = type_info.get("settings", {})
        return settings.get("required", False)
    
    def _is_field_unique(self, type_info: Dict[str, Any]) -> bool:
        """
        判断字段是否唯一
        
        Args:
            type_info: 字段类型信息
            
        Returns:
            是否唯一
        """
        settings = type_info.get("settings", {})
        return settings.get("unique", False)
    
    def _is_field_multiple(self, type_info: Dict[str, Any]) -> bool:
        """
        判断字段是否多选
        
        Args:
            type_info: 字段类型信息
            
        Returns:
            是否多选
        """
        settings = type_info.get("settings", {})
        return settings.get("multiple", False)
    
    def _extract_generation_rules(self, type_info: Dict[str, Any]) -> str:
        """
        提取字段生成规则
        
        Args:
            type_info: 字段类型信息
            
        Returns:
            生成规则JSON字符串
        """
        import json
        
        field_type = type_info.get("name", "")
        settings = type_info.get("settings", {})
        
        rules = {
            "type": field_type,
            "settings": settings
        }
        
        return json.dumps(rules, ensure_ascii=False)
    
    def get_supported_field_types(self) -> List[str]:
        """
        获取支持的字段类型列表
        
        Returns:
            支持的字段类型列表
        """
        return list(self.supported_field_types)
    
    def is_field_type_supported(self, field_type: str) -> bool:
        """
        检查字段类型是否支持
        
        Args:
            field_type: 字段类型
            
        Returns:
            是否支持
        """
        return field_type in self.supported_field_types
    
    def store_metadata(self, object_name: str, metadata: Dict[str, Any]) -> bool:
        """
        存储飞书API元数据到数据库
        
        Args:
            object_name: 对象名称
            metadata: 飞书API返回的元数据
            
        Returns:
            是否成功
        """
        try:
            app_logger.info(f"开始存储元数据：{object_name}")
            
            # 创建数据库引擎和会话
            engine = create_engine(f"mysql+pymysql://{settings.DB_USER}:{settings.DB_PASSWORD}@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}")
            Session = sessionmaker(bind=engine)
            session = Session()
            
            try:
                # 删除现有记录
                existing_count = session.query(FieldSchema).filter(
                    FieldSchema.object_api_name == object_name
                ).delete()
                
                if existing_count > 0:
                    app_logger.info(f"删除了{existing_count}个现有字段记录")
                
                # 解析并存储字段信息
                fields = self.parse_fields(metadata)
                for field_data in fields:
                    field_record = FieldSchema(
                        object_api_name=object_name,
                        field_api_name=field_data["field_api_name"],
                        field_label_zh=field_data["field_label_zh"],
                        field_label_en=field_data["field_label_en"],
                        field_type=field_data["field_type"],
                        is_required=field_data["is_required"],
                        is_unique=field_data["is_unique"],
                        is_multiple=field_data["is_multiple"],
                        generation_rules=field_data["generation_rules"]
                    )
                    session.add(field_record)
                
                session.commit()
                app_logger.info(f"成功存储元数据：{object_name}，共{len(fields)}个字段")
                return True
                
            except Exception as e:
                session.rollback()
                raise e
            finally:
                session.close()
            
        except Exception as e:
            app_logger.error(f"存储元数据异常：{str(e)}")
            return False
    
    def get_stored_fields(self, object_name: str) -> List[Dict[str, Any]]:
        """
        从数据库获取已存储的字段信息
        
        Args:
            object_name: 对象名称
            
        Returns:
            字段信息列表
        """
        try:
            # 创建数据库引擎和会话
            engine = create_engine(f"mysql+pymysql://{settings.DB_USER}:{settings.DB_PASSWORD}@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}")
            Session = sessionmaker(bind=engine)
            session = Session()
            
            try:
                fields = session.query(FieldSchema).filter(
                    FieldSchema.object_api_name == object_name
                ).all()
                
                return [
                    {
                        "field_api_name": field.field_api_name,
                        "field_label_zh": field.field_label_zh,
                        "field_label_en": field.field_label_en,
                        "field_type": field.field_type,
                        "is_required": field.is_required,
                        "is_unique": field.is_unique,
                        "is_multiple": field.is_multiple,
                        "generation_rules": field.generation_rules,
                        "created_at": field.created_at,
                        "updated_at": field.updated_at
                    }
                    for field in fields
                ]
                
            finally:
                session.close()
            
        except Exception as e:
            app_logger.error(f"获取存储的字段信息异常：{str(e)}")
            return []
    
    def process_object_metadata(self, object_name: str) -> bool:
        """
        处理对象元数据的完整流程
        
        Args:
            object_name: 对象名称（如：object_cbb246f2bd1）
            
        Returns:
            是否成功
        """
        try:
            app_logger.info(f"开始处理对象元数据：{object_name}")
            
            # 1. 获取元数据
            metadata = self.get_object_metadata(object_name)
            if not metadata:
                app_logger.error(f"获取元数据失败：{object_name}")
                return False
            
            # 2. 存储元数据
            success = self.store_metadata(object_name, metadata)
            if not success:
                app_logger.error(f"存储元数据失败：{object_name}")
                return False
            
            app_logger.info(f"对象元数据处理完成：{object_name}")
            return True
            
        except Exception as e:
            app_logger.error(f"处理对象元数据异常：{str(e)}")
            return False

# 全局元数据管理器实例
metadata_manager = MetadataManager() 